﻿using System;
using System.IO;
using System.Text;
using System.Net;
using System.Xml;

using ECCIT.Net.SAML2.Assertions;

namespace ECCIT.Net.SAML2.Protocols
{
    public class StatusResponseType
    {
        // Fields
        private string consent;
        private string destination;
        private Extensions extensions;
        private string id;
        private string inResponseTo;
        private DateTime issueInstant;
        private Issuer issuer;
        private XmlElement signature;
        private Status status;
        private string version;

        // Properties
        public string Consent
        {
            get
            {
                return this.consent;
            }
            set
            {
                this.consent = value;
            }
        }

        public string Destination
        {
            get
            {
                return this.destination;
            }
            set
            {
                this.destination = value;
            }
        }

        public Extensions Extensions
        {
            get
            {
                return this.extensions;
            }
            set
            {
                this.extensions = value;
            }
        }

        public string ID
        {
            get
            {
                return this.id;
            }
            set
            {
                this.id = value;
            }
        }

        public string InResponseTo
        {
            get
            {
                return this.inResponseTo;
            }
            set
            {
                this.inResponseTo = value;
            }
        }

        public DateTime IssueInstant
        {
            get
            {
                return this.issueInstant;
            }
            set
            {
                this.issueInstant = value;
            }
        }

        public Issuer Issuer
        {
            get
            {
                return this.issuer;
            }
            set
            {
                this.issuer = value;
            }
        }

        public XmlElement Signature
        {
            get
            {
                return this.signature;
            }
            set
            {
                this.signature = value;
            }
        }

        public Status Status
        {
            get
            {
                return this.status;
            }
            set
            {
                this.status = value;
            }
        }

        public string Version
        {
            get
            {
                return this.version;
            }
            set
            {
                this.version = value;
            }
        }

        // Methods
        public StatusResponseType()
        {
            this.issueInstant = DateTime.MinValue;
            this.id = SAML.CreateID();
            this.version = "2.0";
            this.issueInstant = DateTime.UtcNow;
        }

        public StatusResponseType(XmlElement xmlElement)
        {
            this.issueInstant = DateTime.MinValue;
            if (xmlElement.HasAttribute("ID"))
            {
                this.id = xmlElement.GetAttribute("ID").Trim();
            }
            if (xmlElement.HasAttribute("InResponseTo"))
            {
                this.inResponseTo = xmlElement.GetAttribute("InResponseTo").Trim();
            }
            if (xmlElement.HasAttribute("Version"))
            {
                this.version = xmlElement.GetAttribute("Version").Trim();
            }
            if (xmlElement.HasAttribute("IssueInstant"))
            {
                this.issueInstant = SAML.ToDateTime(xmlElement.GetAttribute("IssueInstant").Trim());
            }
            if (xmlElement.HasAttribute("Destination"))
            {
                this.destination = xmlElement.GetAttribute("Destination").Trim();
            }
            if (xmlElement.HasAttribute("Consent"))
            {
                this.consent = xmlElement.GetAttribute("Consent").Trim();
            }
            foreach (XmlNode node in xmlElement.ChildNodes)
            {
                if (node is XmlElement)
                {
                    XmlElement element = (XmlElement)node;
                    if (Issuer.IsValid(element))
                    {
                        this.issuer = new Issuer(element);
                    }
                    else
                    {
                        if (Extensions.IsValid(element))
                        {
                            this.extensions = new Extensions(element);
                            continue;
                        }
                        if (Status.IsValid(element))
                        {
                            this.status = new Status(element);
                        }
                    }
                }
            }
            this.signature = XmlSignature.GetSignatureElement(xmlElement);
        }

        public bool IsSuccess()
        {
            return ((((this.status != null) && (this.status.StatusCode != null)) && (this.status.StatusCode.Code != null)) && (this.status.StatusCode.Code == "urn:oasis:names:tc:SAML:2.0:status:Success"));
        }

        public void ToXml(XmlElement xmlElement)
        {
            if (!string.IsNullOrEmpty(this.id))
            {
                xmlElement.SetAttribute("ID", this.id);
            }
            if (!string.IsNullOrEmpty(this.inResponseTo))
            {
                xmlElement.SetAttribute("InResponseTo", this.inResponseTo);
            }
            if (!string.IsNullOrEmpty(this.version))
            {
                xmlElement.SetAttribute("Version", this.version);
            }
            if (this.IssueInstant != DateTime.MinValue)
            {
                xmlElement.SetAttribute("IssueInstant", SAML.ToDateTimeString(this.issueInstant));
            }
            if (!string.IsNullOrEmpty(this.destination))
            {
                xmlElement.SetAttribute("Destination", this.destination);
            }
            if (!string.IsNullOrEmpty(this.consent))
            {
                xmlElement.SetAttribute("Consent", this.consent);
            }
            if (this.issuer != null)
            {
                xmlElement.AppendChild(this.issuer.ToXml(xmlElement.OwnerDocument));
            }
            if (this.signature != null)
            {
                xmlElement.AppendChild(xmlElement.OwnerDocument.ImportNode(this.signature, true));
            }
            if (this.extensions != null)
            {
                xmlElement.AppendChild(this.extensions.ToXml(xmlElement.OwnerDocument));
            }
            if (this.status != null)
            {
                xmlElement.AppendChild(this.status.ToXml(xmlElement.OwnerDocument));
            }
        }
    }
}
